<?php
/**
 * 表单验证类
 */
namespace framework\core;
use framework\Flight;

class Validator{

    /**
     * 默认消息.
     * @var array
     */
    protected $defaultMessages = [
        'preg'   => ':attribute 验证规则不正确',
        'same'   => ':attribute 两次输入不一致',
        'empty'  => ':attribute 不能为空',
        'len' 	 =>  ':attribute 长度不正确',
        'type' 	 => ':attribute 用户名类型输入不正确',
        'email'	 => ':attribute 邮箱输入不正确',
        'mobile' => ':attribute 手机号码不正确',
        'tel' 	 =>  ':attribute 固定电话不正确',
        'ip' 	 => ':attribute IP格式不正确',
        'url' 	 => ':attribute 输入网址格式不正确',
    ];

    /**
     * 表单
     * @var array
     */

    protected $input =array();

    /**
     * 验证规则
     * @var array
     */
    protected $rules =array();

    public function __construct($array = array())	{
		if(!isset($array[0][0])){
			$array = func_get_args();
		}
		if(!is_null($array[0]) && is_array($array[0])){
			$this->rules = $array[0];
			$this->input = $this->objarray_to_array(Flight::request()->data);
		}else{
			return false;
		}
    }
	/**
	 * @return bool|mixed|string
	 */
	public function rule(){
		foreach($this->rules as $key => $value){
			if(!array_key_exists($key,$this->input)){
				return "The form input name {$key} not found";
			}
			$function 	= $value[0];   //认证方法
			$message 	= $value[1];   //返回提示(留空默认提示)
			$param	    = $value[2];   //验证表单正则
			if(isset($function)){
				$class_function = 'is'.ucfirst(strtolower($function));
				if(!method_exists('framework\core\Validator',$class_function)){
	            	return "The ".__NAMESPACE__."\\Validator::{$function}() not found";
				}
				$result = self::$class_function($this->input[$key],$param);
				if(!$result){
					if(isset($message)){
						return $message;
					}else{
						return $this->transform($function,$key);
					}
				}
			}
		}
		return true;
	}

	/**
	 * 字符串替换
	 * @param $function
	 * @param $key
	 * @return mixed
	 */
 	protected function transform($function,$key){
		return str_replace(':attribute',$key,$this->defaultMessages[$function]);
    }
    
	/** 
	 * 对象数组转为普通数组 
	 * 
	 * AJAX提交到后台的JSON字串经decode解码后为一个对象数组， 
	 * 为此必须转为普通数组后才能进行后续处理， 
	 * 此函数支持多维数组处理。 
	 * 
	 * @param array 
	 * @return array 
	 */ 
	protected function objarray_to_array($obj) {  
	    $ret = array();  
	    foreach ($obj as $key => $value) {
		    if (is_array($value) || is_object($value)){  
		            $ret[$key] =  $this->objarray_to_array($value);  
		    }else{  
		        $ret[$key] = $value;  
		    }  
	    }  
	    return $ret;
	} 

	//############################################################
	/**
	 * 用正则检验
	 * @param $str
	 * @param $param
	 * @return bool
	 */
	public static function isPreg($str,$param){
		if(empty($str)){
			return true;	
		}
		return preg_match($param,$str) ? true : false;
	}

	/**
	 * 检查两次输入的值是否相同
	 * @param $str
	 * @param $param
	 * @return bool
	 */
    protected function isSame($str,$param){
   		return $str == $this->input[$param];
    }
	/**
	 * 检查字符串是否为空
	 * @param $str
	 * @return bool
	 */
	public static function isEmpty($str){
		$str = trim($str);
		return empty($str) ? false : true;
	}  

	/**
	 * 检查字符串长度
	 * @param $str
	 * @param $param
	 * @return bool
	 */
    public static function isLen($str,$param){
		$min = 0;
		$max = 255;
		if(!is_null($param)){
			$array = explode(',',$param);
			$value = array();
			if(isset($array[0])){
				list($min_name,$min_value) = explode(':', $array[0]);
				$value[$min_name] = $min_value;
			}
			if(isset($array[1])){
				list($max_name,$max_value) = explode(':', $array[1]);
				$value[$max_name] = $max_value;
			}
			$min = array_key_exists('min',$value) ? $value['min'] : 0;
			$max = array_key_exists('max',$value) ? $value['max'] : 255;
		}
		$str = trim($str);
		if(empty($str)){
			return true;
		}
		$len = strlen($str);
		if(($len>=$min)&&($len<=$max)){
			return true;		
		}else{
			return false;	  
		}
	}

	/**
	 * 检查用户名类型
	 * @param $str
	 * @param $param
	 * @return bool
	 */
	public static function isType($str,$param){
		switch($param){	
			//纯英文
			case "EN":$pattern="/^[a-zA-Z]+$/";break;							
			//英文数字                           
			case "INT":$pattern="/^[a-zA-Z0-9]+$/"; break;
			 //允许的符号(|-_字母数字)   
			case "ALL":$pattern="/^[\-\_a-zA-Z0-9]+$/"; break; 
			//用户自定义正则
			default:$pattern = $param;
				break;
		}
		return preg_match($pattern,$str) ? true : false;
     }

	/**
	 * 验证邮箱
	 * @param $str
	 * @return bool
	 */
	public static function isEmail($str){
		if(empty($str)){
			return true;		
		}
		$chars = "/^([a-z0-9+_]|\\-|\\.)+@(([a-z0-9_]|\\-)+\\.)+[a-z]{2,6}\$/i";
		if (strpos($str, '@') !== false && strpos($str, '.') !== false){
			if (preg_match($chars, $str)){
				return true;
			}else{
				return false;
			}
		}else{
			return false;
		}
	}

	/**
	 * 验证手机号码
	 * @param $str
	 * @return bool|int
	 */
	 public  static function isMobile($str){
		if (empty($str)) {
			return true;
		}
		return preg_match('#^13[\d]{9}$|14^[0-9]\d{8}|^15[0-9]\d{8}$|^18[0-9]\d{8}$#', $str);
	}

	/**
	 * 验证固定电话
	 * @param $str
	 * @return bool|int
	 */
	public  static function isTel($str){
		if (empty($str)) {
			return true;
		}
		return preg_match('/^((\(\d{2,3}\))|(\d{3}\-))?(\(0\d{2,3}\)|0\d{2,3}-)?[1-9]\d{6,7}(\-\d{1,4})?$/', trim($str));
	}

	/**
	 * 验证ip
	 * @param $str
	 * @return bool
	 */
	public static function isIp($str){
		if(empty($str)){
			return true;	
		}
		if(!preg_match('#^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$#', $str)) {
			return false;			
		}
		$ip_array = explode('.', $str);
		//真实的ip地址每个数字不能大于255（0-255）		
		return ($ip_array[0]<=255 && $ip_array[1]<=255 && $ip_array[2]<=255 && $ip_array[3]<=255) ? true : false;
	}	

	/**
	 * 验证网址
	 * @param $str
	 * @return bool
	 */
	public  static function isUrl($str) {
		if(empty($str)){
			return true;	
		}
		return preg_match("/^(http|https|ftp|ftps):\/\/[AZaz09]+\.[AZaz09]+[\/=\?%\&_~`@[\]\':+!]*([^<>\"\"])*$/", $str) ? true : false;
	}

	/**
	 * 判断英文
	 * @param $str
	 * @return bool
	 */
	public function isEnglish($str){
		return preg_match("/^[A-Za-z]+$/", $str) ? true : false;
	}

	/**
	 * 判断整数
	 * @param $str
	 * @return bool
	 */
	public function isInteger($str){
		return preg_match("/^[-\+]?\d+$/", $str) ? true : false;
	}
}